package com.hly.musicbackground.model.boots.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hly.musicbackground.Final.FictionFinal;
import com.hly.musicbackground.Final.RedisFinal;
import com.hly.musicbackground.Utils.JsoupBooksUtil;
import com.hly.musicbackground.Utils.RedisUtil;
import com.hly.musicbackground.dao.FictionChapterDao;
import com.hly.musicbackground.dao.FictionDao;
import com.hly.musicbackground.domain.Fiction;
import com.hly.musicbackground.domain.FictionChapter;
import com.hly.musicbackground.model.boots.service.FictionChapterService;
import com.hly.musicbackground.model.boots.service.FictionShelfService;
import com.hly.musicbackground.result.Code;
import lombok.RequiredArgsConstructor;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class FictionChapterServiceImpl extends ServiceImpl<FictionChapterDao, FictionChapter> implements FictionChapterService {

    private final FictionShelfService fictionShelfService;
    private final RedisUtil redisUtil;

    private final FictionDao fictionDao;

    private final FictionDocumentWwwFyhuaboCom fictionDocument;

    @Override
    public List<FictionChapter> DocumentToObject(Document document, int fid) {
        return fictionDocument.DocumentToObjectFictionChapter(document, fid);
    }

    @Override
    public boolean DocumentToObjectAndUpdate(Document document, int fid) {

        List<FictionChapter> fictionChapters = DocumentToObject(document, fid);

        boolean b = false;

        int chapterLength = getChapterLength(fid);

        for (int i = chapterLength - 1; i < fictionChapters.size(); i++) {
            FictionChapter fictionChapter = fictionChapters.get(i);
            FictionChapter one = lambdaQuery().eq(FictionChapter::getFictionId, fid)
                    .eq(FictionChapter::getChapterLink, fictionChapter.getChapterLink()).one();
            if (one == null){
                save(fictionChapter);
                b = true;
            }
        }

        if (b){
            fictionShelfService.updateNewChapter(1, fid);
        }

        return b;
    }

    @Override
    public List<FictionChapter> getAutoFictionChapterList(Fiction fiction) {
        List<FictionChapter> fictionChapters = lambdaQuery()
                .eq(FictionChapter::getFictionId, fiction.getFictionId()).list();

        // 数据不为空，返回数据
        if (fictionChapters.size() != 0){
            return fictionChapters;
        }

        String key = RedisFinal.FICTION_CHAPTER_KEY + fiction.getFictionId();

        try {
            // 获取锁
            boolean isLock = redisUtil.tryLock(key);

            // 锁获取失败，等待数据库更新尝试获取数据
            if (!isLock){
                Thread.sleep(500);
                return getAutoFictionChapterList(fiction);
            }

            // 解析小说目录
            fictionChapters = DocumentToObject(JsoupBooksUtil
                    .getDoc(fiction.getFictionLink()), fiction.getFictionId());

            // 若目录解析后没有数据则将小说标记为异常
            if (fictionChapters.size() == 0){
                fictionDao.updateAbnormal(fiction.getFictionId(), FictionFinal.abnormal_1);
                Code.BUSINESS_ERR("解析目录失败");
            }

            // 保存小说目录
            saveBatch(fictionChapters);
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
            Code.BUSINESS_ERR("解析或保存小说目录失败");
        }finally {
            // 释放锁
            redisUtil.releaseLock(key);
        }

        return fictionChapters;
    }

    @Override
    public FictionChapter getNewChapter(int fictionId) {
        FictionChapter fictionChapter = baseMapper.getNewChapter(fictionId);
        return fictionChapter;
    }

    @Override
    public int getChapterLength(int fictionId) {
        Object len = baseMapper.selectMaps(new QueryWrapper<FictionChapter>()
        .select("count(1) as len").lambda()
        .eq(FictionChapter::getFictionId, fictionId)).get(0).get("len");
        return Integer.valueOf(String.valueOf(len));
    }

    @Override
    public long getFictionChapterCount(int fictionId) {
        return lambdaQuery().eq(FictionChapter::getFictionId, fictionId).count();
    }

    private boolean isChapterI(String name){
        String[] names = {"第一章", "第001章", "第1章", "第01章"};
        String[] ns = {"0001", "001", "1", "一"};

        for (String n : names){
            if (name.indexOf(n) == 0){
                return true;
            }
        }

        for (String n : ns){
            if (n.equals(name.split(" ")[0])){
                return true;
            }
        }
        return false;
    }
}
